package org.jeecg.board.service.impl;/**
 * @Description
 * @Author LiCY
 * @Date 2023/4/24
 */

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.board.dto.*;
import org.jeecg.board.mapper.LineBoardMapper;
import org.jeecg.board.service.LineBoardService;
import org.jeecg.common.api.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 功能描述：
 *
 * @author: LCY
 * @date: 2023年04月24日 14:01
 */
@Service
@Slf4j
public class LineBoardServiceImpl implements LineBoardService {
    @Autowired
    private LineBoardMapper lineBoardMapper;


    @Autowired
    public RedisTemplate redisTemplate;



    @Override
    public Result<Map<String, Object>> getBoardData(Map<String, Object> param) {
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        String key ="boardData"+"-"+line;
        if (redisTemplate.hasKey(key)){
            Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForValue().get(key);
            log.info("从redis获取看板数据");
            return Result.OK(data);
        }else{
            HashMap<String, Object> map = new HashMap<>();
            AtomicReference<Double> passRate = new AtomicReference<>((double) 1);
            List<LineBoardBarDTO> stnFtq = lineBoardMapper.getStnFTQ(param);
            List<LineBoardBarDTO> availability = lineBoardMapper.getAvailability(param);
            List<LineBoardBarDTO> performance = lineBoardMapper.getPerformance(param);
            Integer errorNum = lineBoardMapper.getWoErrorNum(param);
            stnFtq.forEach(item -> {
                passRate.updateAndGet(v ->  (v * item.getValue() * 0.01));
            });
            LineBoardBarDTO minAvailability = availability.stream().min(Comparator.comparing(LineBoardBarDTO::getValue)).get();
            LineBoardBarDTO minPerformance = performance.stream().min(Comparator.comparing(LineBoardBarDTO::getValue)).get();

            map.put("ftq", stnFtq);
            map.put("availability", availability);
            map.put("performance", performance);

            String str = String.format("%.2f", passRate.get() * 100);
            //OEE = 45678不合格数/4站开工数 * 瓶颈工序性能稼动率 * 最低的时间稼动率
            Double totalNum = lineBoardMapper.getTotalNum(param);
            Double ngNum = lineBoardMapper.getNGNum(param);
            Double oee = (totalNum-ngNum)/totalNum * minAvailability.getValue()*0.01 * minPerformance.getValue()*0.01;
            String lineOee = String.format("%.2f", oee* 100);
            map.put("passRate", str);
            map.put("lineOee", lineOee);
            map.put("errorNum", errorNum);
            log.info("存入看板数据到Redis");
            redisTemplate.opsForValue().set(key, map, 120, TimeUnit.SECONDS);
            DynamicDataSourceContextHolder.clear();
            DynamicDataSourceContextHolder.push("master");
            return Result.OK(map);
        }
    }

    @Override
    public Result<Map<String, Object>> getQualityBoardData(Map<String, Object> param) {
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        String key = "QisBoardData"+"-"+line;
        if (redisTemplate.hasKey(key)) {
            Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForValue().get(key);
            if (data != null) {
                Date now = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                String formattedDate = sdf.format(now);
                data.put("time", formattedDate);
            }
            log.info("从redis获取看板数据");
            return Result.OK(data);
        } else {
            HashMap<String, Object> map = new HashMap<>();
            List<String> product = new ArrayList<>(Arrays.asList("OP80", "OP90"));
            List<String> semi1 = new ArrayList<>(Arrays.asList("OP30"));
            List<String> semi = new ArrayList<>(Arrays.asList("OP30", "OP40", "OP50", "OP60", "OP70"));
            AtomicReference<Double> passRate = new AtomicReference<>((double) 1);
            List<LineBoardBarDTO> stnFtq = lineBoardMapper.getStnFTQ(param);
            //计算成品合格率
            Integer productTotalNum = lineBoardMapper.getOpTotalNum(param, product);
            int productError = lineBoardMapper.getOpErrorNum(param, product).size();
            Integer semiTotalNum = lineBoardMapper.getOpTotalNum(param, semi1);
            int semiError = lineBoardMapper.getOpErrorNum(param, semi).size();

            map.put("ftq", stnFtq);
            map.put("productTotalNum", productTotalNum);
            map.put("productError", productError);
            map.put("semiTotalNum", semiTotalNum);
            map.put("semiError", semiError);
            String productPassRate = String.format("%.2f", (productTotalNum-productError)/(double)productTotalNum * 100);
            String semiPassRate = String.format("%.2f", (semiTotalNum-semiError)/(double)semiTotalNum * 100);
            map.put("productPassRate", productPassRate);
            map.put("semiPassRate", semiPassRate);
            //OEE = 45678不合格数/4站开工数 * 瓶颈工序性能稼动率 * 最低的时间稼动率
            map.put("errorNum", 0);
            Date now = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
            String formattedDate = sdf.format(now);
            map.put("time", formattedDate);
            log.info("存入看板数据到Redis");
            redisTemplate.opsForValue().set(key, map, 120, TimeUnit.SECONDS);
            DynamicDataSourceContextHolder.clear();
            DynamicDataSourceContextHolder.push("master");
            return Result.OK(map);
        }
    }

    @Override
    public Result<Map<String, Object>> getBoardData2(Map<String, Object> param) {
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        String key = "lineBoardData"+"-"+line;
        //1 计算小时产量
        HashMap<String, Object> map = new HashMap<>();
        List<String> timeList = lineBoardMapper.getTimeList(param);
        List<Integer> planNum = lineBoardMapper.getPlanNum(param);
        List<Integer> actualNum = lineBoardMapper.getActualNum(param);
        Double todayDowntime = lineBoardMapper.getTodayDowntime(param);
        Double availability =  lineBoardMapper.getLineAvailability(param);
        Double performance =  lineBoardMapper.getLinePerformance(param);
        Double todayQualifiedNum = lineBoardMapper.getTodayQualifiedNum(param);
        Double todayUnqualifiedNum = lineBoardMapper.getTodayUnqualifiedNum(param);
        List<LineBoardBarDTO> unqualifiedCause = lineBoardMapper.getUnqualifiedCause(param);
        List<LineBoardBarDTO> alarmDuration = lineBoardMapper.getAlarmDuration(param);
        List<LineBoardBarDTO> alarmNum = lineBoardMapper.getAlarmNum(param);
        map.put("timeList",timeList);
        map.put("planNum",planNum);
        map.put("actualNum",actualNum);
        map.put("unqualifiedCause",unqualifiedCause);
        map.put("alarmDuration",alarmDuration);
        map.put("alarmNum",alarmNum);
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        // 将要格式化的数字传入 format() 方法进行处理
        double tcr = availability/(todayDowntime*8);
        double pr = performance/(todayDowntime/30);
        double ftq = todayQualifiedNum / (todayQualifiedNum + todayUnqualifiedNum);
        double oee = tcr*pr*ftq;
        map.put("availability",decimalFormat.format(tcr*100));
        map.put("performance",decimalFormat.format(pr*100));
        map.put("ftq",decimalFormat.format(ftq*100));
        map.put("oee",decimalFormat.format(oee*100));
        return Result.OK(map);
    }

    /**
     * 获取产线看板生产数据 （工单进度，小时累计产量，小时产量）
     * @param param
     * @return Result<Map<String, Object>>
     */
    @Override
    public Result<Map<String, Object>> getLineBoardProductionData(Map<String, Object> param) {
        try{
            DynamicDataSourceContextHolder.clear();
            String line = "";
            if (param.containsKey("line")){
                line = (String) param.get("line");
            }
            DynamicDataSourceContextHolder.push("H"+line);
            HashMap<String, Object> map = new HashMap<>();
            String key = "lineBoardData"+"-"+line;
            Integer woIdNum = lineBoardMapper.getWoidNum(param);
            if (Objects.isNull(woIdNum)){
                map.put("woIdNum",0);
            }else{
                map.put("woIdNum",woIdNum);
            }
            //获取完工工位
            String fGOpName = lineBoardMapper.getFgOp(param);
            String bottleneck = lineBoardMapper.getBottleneck();
            if (StringUtils.isBlank(fGOpName)) {
                fGOpName = "OP80";
            }
            map.put("bottleneck", bottleneck);
            param.put("fGOpName", fGOpName);
            Integer beat = lineBoardMapper.getCtNum(param);
            if (beat == null) {
                beat = lineBoardMapper.getProductBeat(param);
                if (beat == null) {
                    beat = 100;
                }
            }
            param.put("beat",beat);
            List<Integer> classPlanTotalNum = lineBoardMapper.getClassPlanTotalNum(param);
            map.put("classPlanTotalNum",classPlanTotalNum);
            List<Integer> classAlarmTotalNum = lineBoardMapper.getClassAlarmTotalNum(param);
            map.put("classAlarmTotalNum",classAlarmTotalNum);
            List<String> classTimeList = lineBoardMapper.getClassTimeList(param);
            map.put("classTimeList",classTimeList);
            Date now = new Date();
            LocalDate now2 = LocalDate.now();
            String currentDate = now2.format(DateTimeFormatter.ofPattern("MM-dd"));
            map.put("currentDate",currentDate);
            map.put("classTimeList",classTimeList);
            param.put("now",now);
            DecimalFormat decimalFormat = new DecimalFormat("#0");
            Double availability =  lineBoardMapper.getLineAvailability(param);
            Double performance =  lineBoardMapper.getLinePerformance(param);
            Double todayDowntime = lineBoardMapper.getTodayDowntime(param);
            Double todayQualifiedNum = lineBoardMapper.getTodayQualifiedNum(param);
            Double todayUnqualifiedNum = lineBoardMapper.getTodayUnqualifiedNum(param);
            int opNum = lineBoardMapper.getOpNum();
            double tcr = availability/(todayDowntime*opNum);
            double pr = performance/(todayDowntime/beat);
            if (Double.isNaN(pr)){
                pr=0.0;
            }
            if (Double.isNaN(tcr)){
                tcr=0.0;
            }
            if (tcr>1.0){
                tcr=1.0;
            }

            if (pr>1.0){
                pr=1.0;
            }
            double ftq = todayQualifiedNum / (todayQualifiedNum + todayUnqualifiedNum);
            if (Double.isNaN(ftq)){
                ftq=0.0;
            }
            if (ftq>1.0){
                ftq=1.0;
            }
            double oee = 0;
            oee = Math.round(tcr * pr * ftq * 100);
            if (oee>100){
                oee=100;
            }
            map.put("availability",decimalFormat.format(tcr*100));
            map.put("performance",decimalFormat.format(pr*100));
            map.put("ftq",decimalFormat.format(ftq*100));
            map.put("oee",decimalFormat.format(oee));
            List<String> lineOPList = lineBoardMapper.getLineOPList(param);
            map.put("lineOPList",lineOPList);
            List<BoardOpDataDTO> opDataDTOList = new ArrayList<>();
            lineOPList.forEach(item->{
                BoardOpDataDTO boardOpDataDTO = new BoardOpDataDTO();
                boardOpDataDTO.setSmooth(true);
                boardOpDataDTO.setName(item);
                boardOpDataDTO.setType("line");
                List<Integer> opPassRate = lineBoardMapper.getOpPassRate(param, item);
                boardOpDataDTO.setData(opPassRate);
                opDataDTOList.add(boardOpDataDTO);
                //map.put(item,opPassRate);
            });
            map.put("opDataDTOList",opDataDTOList);
            //获取当日开班时间
            Integer dayStartTime = lineBoardMapper.getDayStartTime();
            //获取当前时间 判断当前时间如果小于开班时间则日期减一
            LocalDateTime now1 = LocalDateTime.now();
            LocalDateTime STime;
            LocalDateTime yTime;
            int hour = now1.getHour();
            if (dayStartTime>hour){
                //日期减一
                STime = LocalDateTime.of(now1.minusDays(1).toLocalDate(), LocalTime.of(dayStartTime, 0));
            }else{
                STime = LocalDateTime.of(now1.toLocalDate(), LocalTime.of(dayStartTime, 0));
            }
            yTime = LocalDateTime.of(now1.minusDays(1).toLocalDate(), LocalTime.of(dayStartTime, 0));
            param.put("dayStartTime",STime);
            param.put("yesterdayStartTime",yTime);
            List<String> dayTimeList = lineBoardMapper.getDayTimeList(param);
            map.put("dayTimeList",dayTimeList);
            List<LineBoardBarDTO> unqualifiedCause = lineBoardMapper.getUnqualifiedCause(param);
            List<LineBoardBarDTO> alarmDuration = lineBoardMapper.getAlarmDuration(param);
            List<LineBoardBarDTO> yAlarmNum = lineBoardMapper.getYAlarmNum(param);
            List<LineBoardBarDTO> yAlarmDuration = lineBoardMapper.getYAlarmDuration(param);
            List<LineBoardBarDTO> alarmNum = lineBoardMapper.getAlarmNum(param);
//            List<LineBoardBarDTO> ydAlarmDuration = lineBoardMapper.getAlarmDuration(param);
//            List<LineBoardBarDTO> ydAlarmNum = lineBoardMapper.getAlarmNum(param);
            getPercent(alarmDuration);
            getPercent(unqualifiedCause);
            getPercent(alarmNum);
            getPercent(yAlarmNum);
            getPercent(yAlarmDuration);
            map.put("unqualifiedCause",unqualifiedCause);
            map.put("alarmDuration",alarmDuration);
            map.put("alarmNum",alarmNum);
            map.put("yAlarmDuration",yAlarmDuration);
            map.put("yAlarmNum",yAlarmNum);
            List<Integer> planNum = lineBoardMapper.getPlanNum(param);
            List<Integer> actualNum = lineBoardMapper.getActualNum(param);
            map.put("planNum",planNum);
            map.put("actualNum",actualNum);
            List<Double> lineOPRunList = lineBoardMapper.getLineOPRunList(param);
            String start = param.get("start").toString();
            DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try{
                Date date = fmt.parse(start);
                long l = (now.getTime() - date.getTime())/(1000*60);
                List<Double> doubles = new ArrayList<>();
                DecimalFormat df = new DecimalFormat("#.00");
                lineOPRunList.forEach(item->{
                    if (l>=item){
                        double v = l - item;
                        String formattedNumber = df.format(v);
                        double result = Double.parseDouble(formattedNumber);
                        doubles.add(result);
                    }else {
                        doubles.add(0.0);
                    }


                });
                map.put("lineOPStopList",doubles);
            }catch (Exception e){
                e.printStackTrace();
            }

            //List<String> lineOPStopList = lineBoardMapper.getLineOPStopList(param);
            map.put("lineOPRunList",lineOPRunList);
            log.info("存入新看板数据到Redis");
            redisTemplate.opsForValue().set(key, map, 7, TimeUnit.DAYS);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DynamicDataSourceContextHolder.clear();
            DynamicDataSourceContextHolder.push("master");
        }
        return Result.OK("执行成功");
    }

    @Override
    public Result<Map<String, Object>> getNewLineBoardProductionData(Map<String, Object> param) {
        DynamicDataSourceContextHolder.clear();
        DynamicDataSourceContextHolder.push("history");
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        HashMap<String, Object> map = new HashMap<>();
        String key = "newlineBoardData"+"-"+line;
        //获取完工工位
        String fGOpName = lineBoardMapper.getFgOp(param);
        if (StringUtils.isBlank(fGOpName)) {
            fGOpName = "OP80";
        }
        param.put("fGOpName", fGOpName);
        Integer beat = lineBoardMapper.getCtNum(param);
        if (beat == null) {
            beat = lineBoardMapper.getProductBeat(param);
            if (beat == null) {
                beat = 45;
            }
        }
//        Integer beat = lineBoardMapper.getProductBeat(param);
//        if (beat == null) {
//            beat = 50;
//        }
        param.put("beat",beat);
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        DecimalFormat decimalFormat1 = new DecimalFormat("#0.0");
        DecimalFormat decimalFormat2 = new DecimalFormat("#0");
        Double availability =  lineBoardMapper.getLineAvailability(param);

        Double totalTime = lineBoardMapper.getTotalTime(param);
        //总运行时长毫秒
        Double totalRunTime = lineBoardMapper.getTotalRunningTime(param);
        //本月总运行时长毫秒
        Double totalRunTimeM = lineBoardMapper.getTotalRunningTimeForCurrentMonth(param);
        //当日总运行时长毫秒
        Double totalRunTimeD = lineBoardMapper.getTotalRunningTimeForCurrentDay(param);
        //当日总停机时长毫秒
        Double totalStopTimeD = lineBoardMapper.getTotalStopTimeForCurrentDay(param);
//        Double performance =  lineBoardMapper.getLinePerformance(param);
        //截至当前时刻已耗时多少秒
        Double todayDowntime = lineBoardMapper.getTodayDowntime(param);
        int opNum = lineBoardMapper.getOpNum();
        double tcr = availability/(todayDowntime*opNum);
        double runRate = totalRunTimeD/totalTime;
//        double pr = performance/(todayDowntime/beat);
//        double ftq = todayQualifiedNum / (todayQualifiedNum + todayUnqualifiedNum);
//        double oee = tcr*pr*ftq;
        map.put("availability",decimalFormat.format(tcr*100));
        map.put("oee",decimalFormat.format(tcr*100));
        map.put("totalRunTime",decimalFormat1.format(totalRunTime/60/60));
        map.put("totalRunTimeM",decimalFormat1.format(totalRunTimeM/60/60));
        map.put("totalRunTimeD",decimalFormat1.format(totalRunTimeD/60/60));
        map.put("totalStopTimeD",decimalFormat1.format(totalStopTimeD/60/60));
        map.put("runRate",decimalFormat2.format(runRate*100));
        if (totalRunTimeD == 0.0) {
            map.put("ftq",decimalFormat.format(0));
            map.put("performance",decimalFormat.format(0));
        } else {
            map.put("ftq",decimalFormat.format(100));
            map.put("performance",decimalFormat.format(100));
        }
        if (totalStopTimeD == 0.0) {
            map.put("stopRate",decimalFormat2.format(0.0));
        } else {
            map.put("stopRate",decimalFormat2.format((1-runRate)*100));
        }

//        map.put("opDataDTOList",opDataDTOList);
//        List<LineBoardBarDTO> unqualifiedCause = lineBoardMapper.getUnqualifiedCause(param);
//        List<LineBoardBarDTO> alarmDuration = lineBoardMapper.getAlarmDuration(param);
//        List<LineBoardBarDTO> alarmNum = lineBoardMapper.getAlarmNum(param);
//        getPercent(alarmDuration);
//        getPercent(unqualifiedCause);
//        getPercent(alarmNum);
//        map.put("unqualifiedCause",unqualifiedCause);
//        map.put("alarmDuration",alarmDuration);
//        map.put("alarmNum",alarmNum);
//        List<Integer> planNum = lineBoardMapper.getPlanNum(param);
//        List<Integer> actualNum = lineBoardMapper.getActualNum(param);
//        map.put("planNum",planNum);
//        map.put("actualNum",actualNum);
//        List<Double> lineOPRunList = lineBoardMapper.getLineOPRunList(param);
//        String start = param.get("start").toString();
//        DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        try{
//            Date date = fmt.parse(start);
//            Date now = new Date();
//            long l = (now.getTime() - date.getTime())/(1000*60);
//            List<Double> doubles = new ArrayList<>();
//            DecimalFormat df = new DecimalFormat("#.00");
//            lineOPRunList.forEach(item->{
//                double v = l - item;
//                String formattedNumber = df.format(v);
//                double result = Double.parseDouble(formattedNumber);
//                doubles.add(result);
//            });
//            map.put("lineOPStopList",doubles);
//        }catch (Exception e){
//            e.printStackTrace();
//        }

        //List<String> lineOPStopList = lineBoardMapper.getLineOPStopList(param);
//        map.put("lineOPRunList",lineOPRunList);
        log.info("存入新产线看板OEE数据到Redis");
        redisTemplate.opsForValue().set(key, map, 7, TimeUnit.DAYS);
        return Result.OK(map);
    }

    private void getPercent(List<LineBoardBarDTO> list){
        AtomicReference<Double> num = new AtomicReference<>(0.0);
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        list.forEach(item->{
            num.updateAndGet(v -> new Double((double) (v + item.getValue())));
        });
        list.forEach(item->{
            item.setPercent(decimalFormat.format(item.getValue()/num.get()*100));
        });
    }
    @Override
    public Result<Map<String, Object>> getLineBoardData(Map<String, Object> param) {
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        String key = "lineBoardData"+"-"+line;
        Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForValue().get(key);
        log.info("从redis获取看板数据");
        return Result.OK(data);
    }

    public List<String> generateLastSevenDays() {
        List<String> dates = new ArrayList<>();
        LocalDate today = LocalDate.now();
        for (int i = 0; i < 7; i++) {
            LocalDate localDate = today.minusDays(i);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
            String formattedDate = localDate.format(formatter);
            dates.add(formattedDate);
        }
        return dates;
    }
    @Override
    public Result<Map<String, Object>> getNewLineBoardData(Map<String, Object> param) {
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        String key = "newlineBoardData"+"-"+line;
        Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForValue().get(key);
        log.info("从redis获取看板数据");
        return Result.OK(data);
    }

    @Override
    public Result<Map<String, Object>> getQisLineBoardData(Map<String, Object> param) {
        DynamicDataSourceContextHolder.clear();
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        DynamicDataSourceContextHolder.push("H"+line);
        HashMap<String, Object> map = new HashMap<>();
        String key = "qisLineBoardData"+"-"+line;
        try {
            log.info("查询报警数据开始{}", LocalDateTime.now());
            List<BoardDataDTO> equipmentAlarmsByLine = lineBoardMapper.getEquipmentAlarmsByLine(param);
            log.info("查询报警数据结束{}", LocalDateTime.now());
            map.put("equipmentAlarms",equipmentAlarmsByLine);
            //获取成品工序 半成品工序 包装工序
            List<String> shiftDate = generateLastSevenDays();
            map.put("shiftDate",shiftDate);
            //4.当月产线数据
            log.info("查询当月产线数据开始{}", LocalDateTime.now());
            //已包装
            Integer monthPackTotal  =lineBoardMapper.getLinePackTotal(param,"month");
            Integer woPackTotal  =lineBoardMapper.getLinePackTotal(param,"wo");
            Integer dayPackTotal  =lineBoardMapper.getLinePackTotal(param,"day");
            //产出
            Integer monthProductTotal  =lineBoardMapper.getLineProductTotal(param,"month");
            Integer woProductTotal  =lineBoardMapper.getLineProductTotal(param,"wo");
            Integer dayProductTotal  =lineBoardMapper.getLineProductTotal(param,"day");
            //成品报废数
            QisBoardDataDTO month = lineBoardMapper.getLineProductScrapTotal(param, "month");
            month.setPackNum(monthPackTotal);
            QisBoardDataDTO wo = lineBoardMapper.getLineProductScrapTotal(param, "wo");
            wo.setPackNum(woPackTotal);
            QisBoardDataDTO day = lineBoardMapper.getLineProductScrapTotal(param, "day");
            if(Objects.isNull(day)){
                day = new QisBoardDataDTO();
                day.setProductScrap(0);
                day.setSemiScrap(0);
            }
            day.setPackNum(dayPackTotal);
            //待拍X光
            try{
                QisBoardDataDTO month1 = lineBoardMapper.getLineXRayTotal(param, "month");
                QisBoardDataDTO wo1 = lineBoardMapper.getLineXRayTotal(param, "wo");
                QisBoardDataDTO day1 = lineBoardMapper.getLineXRayTotal(param, "day");
                //半成品报废
                getFtqAndScrap(month,month1,monthProductTotal);
                getFtqAndScrap(wo,wo1,woProductTotal);
                getFtqAndScrap(day,day1,dayProductTotal);
            }catch (Exception e){
                e.printStackTrace();
            }
            map.put("monthPack",month.getPackNum());
            map.put("monthProductScrap",month.getProductScrap());
            map.put("monthXray",month.getXRay());
            map.put("monthSemi",month.getSemiScrap());
            //Double monthQty = (double) (productNum/qty);
            map.put("monthFTQ",month.getFtq());
            map.put("monthScrap",month.getScrap());
            //5.当前生产工单
            map.put("woPack",wo.getPackNum());
            map.put("woProductScrap",wo.getProductScrap());
            map.put("woXray",wo.getSemiScrap());
            map.put("woSemi",wo.getSemiScrap());
            map.put("woFTQ",wo.getFtq());
            map.put("woScrap",wo.getScrap());
            map.put("woDto",wo);
            //6.当天产线数据
            map.put("dayPack",day.getPackNum());
            map.put("dayProductScrap",day.getProductScrap());
            map.put("dayXray",day.getXRay());
            map.put("daySemi",day.getSemiScrap());
            map.put("dayFTQ",day.getFtq());
            map.put("dayScrap",day.getScrap());
            map.put("dayDto",day);
            //7.当月产品FTQ及报废率
            List<Double> list = new ArrayList<>();
            list.add(80.5);
            map.put("monthQtyList",list);
            List<Double> scrapList = new ArrayList<>();
            scrapList.add(1.86);
            map.put("monthScrapList",scrapList);
            //8.月度&周不良趋势图
            map.put("monthWeekList",scrapList);
            //9.当班次工站不良品统计
            List<BoardDataDTO> shiftOpUnhealthyList  = lineBoardMapper.getShiftOpUnhealthyList(param);
            map.put("shiftOpUnhealthyList",shiftOpUnhealthyList);
            //10.当月产线FTQ&报废率
            List<UnhealthyBoardDataDTO> monthUnhealthyByLine = lineBoardMapper.getMonthUnhealthyByLine(param,"month");
            //11.当工单产线FTQ&报废率
            List<UnhealthyBoardDataDTO> woUnhealthyByLine = lineBoardMapper.getMonthUnhealthyByLine(param,"wo");
            //12.当日产线FTQ&报废率
            List<UnhealthyBoardDataDTO> dayUnhealthyByLine = lineBoardMapper.getMonthUnhealthyByLine(param,"day");
            //13.当班次产线FTQ&报废率
            List<UnhealthyBoardDataDTO> shiftUnhealthyByLine = lineBoardMapper.getMonthUnhealthyByLine(param,"shift");
            map.put("monthUnhealthyByLine",monthUnhealthyByLine);
            map.put("woUnhealthyByLine",woUnhealthyByLine);
            map.put("dayUnhealthyByLine",dayUnhealthyByLine);
            map.put("shiftUnhealthyByLine",shiftUnhealthyByLine);
            log.info("存入新质量看板数据到Redis");
            redisTemplate.opsForValue().set(key, map, 7, TimeUnit.DAYS);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DynamicDataSourceContextHolder.clear();
            DynamicDataSourceContextHolder.push("master");
        }
        return Result.OK(map);
    }

    @Override
    public Result<Map<String, Object>> getLineAndonBoardData(Map<String, Object> param) {
        DynamicDataSourceContextHolder.clear();
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        DynamicDataSourceContextHolder.push("H"+line);
        HashMap<String, Object> map = new HashMap<>();
        String key = "lineAndonBoardData"+"-"+line;
        Integer beat = lineBoardMapper.getCtNum(param);
        if (beat == null) {
            beat = lineBoardMapper.getProductBeat(param);
            if (beat == null) {
                beat = 100;
            }
        }
        //获取当日开班时间
        Integer dayStartTime = lineBoardMapper.getDayStartTime();
        //获取当前时间 判断当前时间如果小于开班时间则日期减一
        LocalDateTime now1 = LocalDateTime.now();
        LocalDateTime STime;
        int hour = now1.getHour();
        if (dayStartTime>hour){
            //日期减一
            STime = LocalDateTime.of(now1.minusDays(1).toLocalDate(), LocalTime.of(dayStartTime, 0));
        }else{
            STime = LocalDateTime.of(now1.toLocalDate(), LocalTime.of(dayStartTime, 0));
        }
        param.put("start",STime);
        param.put("dayStartTime",STime);
        //获取产线产量数据
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        Double availability =  lineBoardMapper.getLineAvailability(param);
        Double performance =  lineBoardMapper.getLinePerformance(param);
        Double todayDowntime = lineBoardMapper.getTodayDowntime(param);
        Double todayQualifiedNum = lineBoardMapper.getTodayQualifiedNum(param);
        Double todayUnqualifiedNum = lineBoardMapper.getTodayUnqualifiedNum(param);
        int opNum = lineBoardMapper.getOpNum();
        double tcr = availability/(todayDowntime*opNum);
        double pr = performance/(todayDowntime/beat);
        Integer target = (int) (todayDowntime/beat);
        double ftq = todayQualifiedNum / (todayQualifiedNum + todayUnqualifiedNum);
        double oee = tcr*pr*ftq;
        map.put("availability",decimalFormat.format(tcr*100));
        map.put("performance",decimalFormat.format(pr*100));
        map.put("ftq",decimalFormat.format(ftq*100));
        map.put("oee",decimalFormat.format(oee*100));
        map.put("target",target);

        List<String> dayTimeList = lineBoardMapper.getDayTimeList(param);
        map.put("dayTimeList",dayTimeList);
        List<Integer> planNum = lineBoardMapper.getPlanNum(param);
        List<Integer> actualNum = lineBoardMapper.getActualNum(param);
        AtomicReference<Integer> sum = new AtomicReference<>(0);
        actualNum.forEach(item->{
            sum.updateAndGet(v -> v + item);
        });
        map.put("planNum",planNum);
        map.put("actualNum",actualNum);
        map.put("actual",sum.get());
        map.put("gap",target-sum.get());
        List<LineBoardBarDTO> alarmNum = lineBoardMapper.getAlarmNum(param);
        getPercent(alarmNum);
        map.put("alarmNum",sum.get());
        log.info("存入安灯看板数据到Redis");
        redisTemplate.opsForValue().set(key, map, 7, TimeUnit.DAYS);
        DynamicDataSourceContextHolder.clear();
        DynamicDataSourceContextHolder.push("master");
        return Result.OK(map);
    }

    @Override
    public Result<Map<String, Object>> getAndonBoardData(Map<String, Object> param) {
        String line = "";
        if (param.containsKey("line")){
            line = (String) param.get("line");
        }
        String key = "lineBoardData"+"-"+line;
        Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForValue().get(key);
        log.info("从redis获取安灯看板数据");
        return Result.OK(data);
    }

    void getFtqAndScrap(QisBoardDataDTO dto,QisBoardDataDTO dto2,Integer productTotal){
        Integer totalNum = dto2.getTotalNum();
        Integer xRay = dto2.getXRay();
        Integer packNum = dto.getPackNum();
        Integer productScrap = dto.getProductScrap();
        Integer semiScrap = dto.getSemiScrap();
        DecimalFormat df = new DecimalFormat("#.00");
        double ftq = (double) (productTotal) /totalNum*100;
        double scrap = (double) (productScrap + semiScrap) /totalNum*100;
        if (ftq>100){
            ftq=100-scrap;
        }
        String format = df.format(ftq);
        String s = df.format(scrap);
        dto.setTotalNum(totalNum);
        dto.setXRay(xRay);
        dto.setFtq(Double.parseDouble(format));
        dto.setScrap(Double.parseDouble(s));
    }
}
